package com.example.meeting.controller;

import cn.hutool.json.JSONObject;
import com.example.meeting.config.MyHandler;
import com.example.meeting.model.domain.Meeting;
import com.example.meeting.model.domain.Person;
import com.example.meeting.model.domain.Subject;
import com.example.meeting.model.responseData.CommonResult;
import com.example.meeting.service.IMeetingService;
import com.example.meeting.service.IPersonService;
import com.example.meeting.service.ISubjectService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
public class SubjectController {
    @Autowired
    private ISubjectService subjectService;
    @Autowired
    private IMeetingService meetingService;
    @Autowired
    private IPersonService personService;

    /**
     * 查询对应id的议题信息
     * @param id
     * @return
     */
    @RequiresAuthentication
    @GetMapping("/subject/{id}")
    public CommonResult selectSubjectById(@PathVariable Long id) {
        Subject subject = subjectService.selectSubjectById(id);
        if (subject == null) {
            return CommonResult.fail("查询失败，没有该议题！");
        }
        return CommonResult.success(subject);
    }

    /**
     * 分页动态查询所有议题信息
     * @param page
     * @param pageSize
     * @param subject    查询条件的议题对象，哪一个有值查询对应的议题列表，多个值则查询同时满足条件的议题
     * @return
     */
    @RequiresAuthentication
    @PostMapping("/subjectList")
    public CommonResult selectSubjectList(@RequestParam(value = "page",defaultValue = "1") Integer page,
                                          @RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize,
                                          @RequestBody Subject subject) {
        PageInfo<Subject> subjectList = subjectService.selectSubjectList(page,pageSize,subject);
        if (subjectList == null) {
            return CommonResult.fail("查询失败，没有任何议题信息");
        }
        return CommonResult.success(subjectList);
    }

    /**
     * 新增议题信息
     * @param subject
     * @return
     */
    @RequiresAuthentication
    @PostMapping("/meeting/{mid:\\d+}/subject")
    public CommonResult addSubject(@Validated @RequestBody Subject subject, @PathVariable Long mid) {
        subject.setStatus(0);
        subject.setMeeting(new Meeting(){{
            setId(mid);
        }});
        subjectService.addSubject(subject);
        // 通知前端添加议题
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("type","addSubject");
        jsonObject.set("data",subject);
        MyHandler.sendMessage(mid, jsonObject.toString());
        return CommonResult.success(subject.getId());
    }

    /**
     * 更新议题信息
     * @param subject
     * @return
     */
    @RequiresAuthentication
    @PutMapping("/subject")
    public CommonResult updateSubject(@RequestBody Subject subject) {
        if (subject.getId() == null) {
            return CommonResult.fail("议题id不能为空");
        }
        subjectService.updateSubject(subject);
        // 通知前端重新拉取议题信息
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("type","repullMeeting");
        MyHandler.broadcastMessage(jsonObject.toString());
        return CommonResult.success();
    }

    /**
     * 删除对应id的议题信息
     * @param id
     * @return
     */
    @RequiresAuthentication
    @DeleteMapping("/subject/{id}")
    public CommonResult deleteSubject(@PathVariable Long id) {
        Integer res = subjectService.deleteSubject(id);
        if (res == 0) {
            return CommonResult.fail("删除议题失败");
        }
        // 通知前端删除议题
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("type","removeSubject");
        jsonObject.set("data",id);
        MyHandler.broadcastMessage(jsonObject.toString());
        return CommonResult.success();
    }

    /**
     * 删除议题对应的列席成员
     * @param s_id
     * @param p_id
     * @return
     */
    @RequiresAuthentication
    @DeleteMapping("/subject")
    public CommonResult deletePersonAndSub(@RequestParam("s_id") Integer s_id,
                                           @RequestParam("p_id") Integer p_id) {
        Integer res = subjectService.deletePersonAndSub(s_id,p_id);
        if (res == 0) return CommonResult.fail("删除议题人员失败");
        return CommonResult.success(1);
    }



    /**
     * 设置议题状态
     */
    @RequiresAuthentication
    @PutMapping("/subject/{sid:\\d+}/status/{status:\\d}")
    public CommonResult unstartSubject(@PathVariable Long sid, @PathVariable Integer status){
        //设置状态
        Subject data = new Subject();
        data.setId(sid);
        data.setStatus(status);
        Integer res = subjectService.updateSubjectStatus(data);
        if (res==0){
            return CommonResult.fail("设置议题状态失败，可能是议题不存在或状态无变化");
        }
        // 通知前端议题状态变更
        JSONObject jsonObject = new JSONObject();
        JSONObject dataObject = new JSONObject();
        jsonObject.set("type","updateSubjectStatus");
        jsonObject.set("data",dataObject);
        dataObject.set("subjectId",sid);
        dataObject.set("status",status);
        Long mid = meetingService.selectMeetingBySubjectId(sid).getId();
        MyHandler.sendMessage(mid, jsonObject.toString());
        return CommonResult.success();
    }

    /**
     * 临时新增列席成员
     * @param subject
     * @throws IOException
     */
    @PostMapping("/subject/temp")
    @RequiresAuthentication
    public CommonResult addPersonTemp(@RequestBody Subject subject) throws IOException {
        log.info(subject.toString());

        if(subject==null || subject.getId()==null || subject.getPersonList()==null){
            return CommonResult.fail("缺少请求参数");
        }
        //校验是否有已存在的成员id，如果有则不二次添加
        Subject data = subjectService.selectSubjectById(subject.getId());
        List<Person> paramPersons = subject.getPersonList();
        List<Person> dataPersons = data.getPersonList();
        for (int i=0;i<paramPersons.size();i++){
            for (int j=0;j<dataPersons.size();j++){
                if (paramPersons.get(i).equals(dataPersons.get(j))){
                    paramPersons.remove(i);
                }
            }
        }


        if (paramPersons.isEmpty()){
            return CommonResult.fail("没有新增的成员");
        }

        //添加议题成员记录
        subjectService.addSubjectPerson(subject.getId(), paramPersons);
        List<Person> resultPersons = personService.selectPersonListByIds(paramPersons.stream().map(Person::getId).collect(Collectors.toList()));

        // 通知前端临时人员名单
        JSONObject jsonObject = new JSONObject();
        JSONObject dataObject = new JSONObject();
        jsonObject.set("type","addTempPersons");
        jsonObject.set("data",dataObject);
        dataObject.set("tempPersons",resultPersons);
        dataObject.set("subjectId",subject.getId());
        Long mid = meetingService.selectMeetingBySubjectId(subject.getId()).getId();
        MyHandler.sendMessage(mid, jsonObject.toString());

        return CommonResult.success();
    }

    /**
     * 批量调整议题权重
     * @param subjectList
     * @throws IOException
     */
    @PostMapping("/subject/adjustWeightBatch")
    @RequiresAuthentication
    public CommonResult adjustWeightBatch(@RequestBody List<Subject> subjectList) throws IOException {
        //校验参数
        if (subjectList == null || subjectList.isEmpty()){
            return CommonResult.fail("缺少请求参数");
        }
        for (Subject subject : subjectList) {
            if(subject == null || subject.getId() == null){
                return CommonResult.fail("议题或议题id不得为空");
            }
        }

        // 生成权重
        int weight = 114514;
        for (Subject subject : subjectList) {
            subject.setWeight(weight);
            weight--;
        }

        //批量调整议题权重
        Integer res = subjectService.updateSubjectWeightBatch(subjectList);
        if (res == 0){
            return CommonResult.success();
        }

        // 通知前端重新拉取议题信息
        Long mid = meetingService.selectMeetingBySubjectId(subjectList.get(0).getId()).getId();
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("type","repullMeeting");
        MyHandler.sendMessage(mid, jsonObject.toString());

        return CommonResult.success();
    }
}
